#include "TabTipNotification.h"
#include "TabTipSystemBase.h"
#include "TabTipSysServer2016.h"
#include "misc\CRegMgr.h"
#include "wndipc\IPCWndServer.h"
#include "TabTipNotification\Utility.h"

BOOL EnableChangeNotifyPriv()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_CHANGE_NOTIFY_NAME, &luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    BOOL bRet = AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);
    CloseHandle(hToken);
    return bRet;
}

CTabTipNotification::CTabTipNotification() 
    : m_pTabTip(NULL)
    , m_bListeningTabTip(false)
    , m_pRegMgr(NULL)
{
    std::string strWindVer = Utility::getWindowsVersion();
    if (strWindVer == "2000" ||
        strWindVer == "XP" ||
        strWindVer == "2003" ||
        strWindVer == "2008" ||
        strWindVer == "Vista" ||
        strWindVer == "2008R2" ||
        strWindVer == "7" ||
        strWindVer == "8" ||
        strWindVer == "2012R2" ||
        strWindVer == "8.1")
    {
        printf("current os version is:%s, and not support tabtip notification.", strWindVer.c_str());
        return;
    }
    EnableChangeNotifyPriv();
    m_pRegMgr = new CRegMgr;
    RegistTabTipMember();

    int iSystemType = strWindVer == "2016" ? TabTipSysServer2016 : TabTipSysBase;
    m_pRegMgr->CreateRegObj(reinterpret_cast<PVOID*>(&m_pTabTip), NULL, iSystemType);
}

CTabTipNotification::~CTabTipNotification()
{
    SAFEDELEPTR(m_pTabTip);
    UnRegistTabTipMember();
    SAFEDELEPTR(m_pRegMgr);
}

bool CTabTipNotification::RegistTabTipMember()
{
    if (m_pRegMgr)
    {
        m_pRegMgr->Register(CRegHelperT<CTabTipSystemBase>(), true);
        m_pRegMgr->Register(CRegHelperT<CTabTipSysServer2016>(), true);
    }
    return true;
}

bool CTabTipNotification::UnRegistTabTipMember()
{
    if (m_pRegMgr)
    {
        m_pRegMgr->UnRegister(CTabTipSystemBase::GetRegItemName(), CTabTipSystemBase::GetRegType());
        m_pRegMgr->UnRegister(CTabTipSysServer2016::GetRegItemName(), CTabTipSysServer2016::GetRegType());
    }
    return true;
}

bool CTabTipNotification::StartListenNotification()
{
    if (m_bListeningTabTip)
    {
        return true;
    }
    if (!m_pTabTip)
    {
        return false;
    }
    m_bListeningTabTip = true;
    return m_pTabTip->InstallNotification();
}

bool CTabTipNotification::StopListenNotification()
{
    if (!m_bListeningTabTip)
    {
        return true;
    }
    if (!m_pTabTip)
    {
        return false;
    }
    m_bListeningTabTip = false;
    return m_pTabTip->UninstallNotification();
}
